package com.umessage.hotel.service.impl;

import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.SortedMap;
import java.util.TreeMap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.riversoft.weixin.pay.base.PaySetting;
import com.riversoft.weixin.pay.payment.Payments;
import com.riversoft.weixin.pay.payment.bean.UnifiedOrderRequest;
import com.riversoft.weixin.pay.payment.bean.UnifiedOrderResponse;
import com.riversoft.weixin.pay.util.SignatureUtil;
import com.umessage.common.service.impl.BaseService;
import com.umessage.common.util.Atools;
import com.umessage.hotel.dao.MemberInfoMapper;
import com.umessage.hotel.dao.OrderBreakfastMapper;
import com.umessage.hotel.domain.BreakfastCoupon;
import com.umessage.hotel.domain.DiningRoom;
import com.umessage.hotel.domain.MemberInfo;
import com.umessage.hotel.domain.OrderBreakfast;
import com.umessage.hotel.domain.OrderInfo;
import com.umessage.hotel.domain.RoomInfo;
import com.umessage.hotel.domain.WxCfg;
import com.umessage.hotel.model.PaySignModel;
import com.umessage.hotel.service.BreakfastCouponService;
import com.umessage.hotel.service.DiningRoomService;
import com.umessage.hotel.service.MemberInfoService;
import com.umessage.hotel.service.OrderBreakfastService;
import com.umessage.hotel.service.RoomInfoService;
import com.umessage.hotel.service.WxCfgService;
import com.umessage.hotel.util.HotelConstant;
import com.umessage.hotel.util.RestResult;

@Service("orderBreakfastService")
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class OrderBreakfastServiceImpl extends BaseService<OrderBreakfast> implements OrderBreakfastService {
	
	private Logger logger = LoggerFactory.getLogger(OrderInfoServiceImpl.class);

	private DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
	@Autowired
	private RoomInfoService roomInfoService;
	@Autowired
	private BreakfastCouponService breakfastCouponService;
	@Autowired
	private OrderBreakfastMapper orderBreakfastMapper;
	@Autowired
	private MemberInfoMapper memberInfoMapper;
	@Autowired
	private WxCfgService wxCfgService;
	@Autowired
	private DiningRoomService diningRoomService;
	@Autowired
	private MemberInfoService memberInfoService;
	
	@Value("${umessage.miniprogramServerUrl}")
	private String miniprogramServerUrl;
	/**
	 * 生成早餐订单
	 * @throws Exception 
	 */
	@Override
	@Transactional
	public OrderBreakfast addOrderBreakfast(OrderBreakfast obf) {
		try {
			MemberInfo member = this.memberInfoMapper.selectByPrimaryKey(obf.getMemberId());
			String hotelId=member.getHotelId();
			DiningRoom dnr=new DiningRoom();
			dnr.setHotelId(Long.valueOf(hotelId));
			DiningRoom dnm=this.diningRoomService.findDiningRoom(dnr);
			String unitPrice = dnm.getUnitPrice();
			BigDecimal unitPriceNum=new BigDecimal(unitPrice);
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
			Calendar calst = Calendar.getInstance();
			Calendar caled = Calendar.getInstance();
			Date start=sdf.parse(obf.getValidStart());//开始时间
			Date end=sdf.parse(obf.getValidEnd());//结束时间
		    calst.setTime(start);
		    caled.setTime(end);
		    //设置开始时间为0时   
		    calst.set(Calendar.HOUR_OF_DAY, 0);   
		    calst.set(Calendar.MINUTE, 0);   
			calst.set(Calendar.SECOND, 0); 
			//设置结束时间为0时   
			caled.set(Calendar.HOUR_OF_DAY, 0);   
			caled.set(Calendar.MINUTE, 0);   
			caled.set(Calendar.SECOND, 0); 
			int days = ((int)(caled.getTime().getTime()/1000)-(int)(calst.getTime().getTime()/1000))/3600/24 + 1;
		    BigDecimal sumPrice = unitPriceNum.multiply(new BigDecimal(obf.getNumDaily())).multiply(BigDecimal.valueOf(days));
		    obf.setMobile(member.getMobile());
		    obf.setUnitPrice(unitPriceNum);
		    obf.setSumPrice(sumPrice);
		    obf.setAddTime(new Date());
			//生成订单数据
			orderBreakfastMapper.addOrderBreakfast(obf);
			return obf;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 支付 订单
	 * @throws Exception 
	 */
	@Override
	@Transactional
	public PaySignModel payOrderBKF(OrderBreakfast obf,String createdIp) throws Exception {
			Integer bfOrderId=obf.getBfOrderId();
			if(bfOrderId==null) {
				throw new Exception("支付订单id为空");
			}
			OrderBreakfast orderBKF = this.selectByKey(bfOrderId);
			//订单不存在
			if (orderBKF == null) {
				throw new RuntimeException("invalid order id");
			}
			// 订单已支付
			if ("1".equals(orderBKF.getPayStatus())) {
				throw new RuntimeException("订单已支付");
			}
			//调取微信
			PaySignModel paySignModel = payWeixin(createdIp, orderBKF);
			return paySignModel;
	}
	/**
	 * 微信支付
	 * @param wxcfgid
	 * @param openid
	 * @param createdIp
	 * @param orderInfo
	 * @return
	 */
	private PaySignModel payWeixin(String createdIp, OrderBreakfast orderBKF) {
		WxCfg wxCfg = wxCfgService.queryWxCfg(orderBKF.getHotelId(), "1");
		if(wxCfg == null) return null;
		String wxcfgid= wxCfg.getWxcfgid();
		// 微信支付通知
		String notifyUrl = miniprogramServerUrl+"/rest/orderBreakfast/" + wxcfgid + "/"
				+ orderBKF.getBfOrderId() + "/payNotify";
		String openid=orderBKF.getOpenid();
		PaySignModel signModel = new PaySignModel();
		PaySetting set = new PaySetting();
		set.setAppId(wxCfg.getAppId());
		set.setMchId(wxCfg.getMchId());
		set.setKey(wxCfg.getAppkey());
		set.setCertPath(wxCfg.getApiclientCert());
		set.setCertPassword(wxCfg.getMchId());

		Payments pay = Payments.with(set);
		UnifiedOrderRequest req = new UnifiedOrderRequest();
		req.setBody("早餐订单支付");
		req.setTradeNumber(orderBKF.getBfOrderSn());
		//req.setTotalFee(1);//测试阶段修改为1分钱			
		req.setTotalFee(orderBKF.getSumPrice().multiply(BigDecimal.valueOf(100)).intValue());// 元转换为分 * 100
		req.setBillCreatedIp(createdIp);
		req.setNotifyUrl(notifyUrl);
		req.setTradeType("JSAPI");// 小程序类型取值
		//req.setProductId(String.valueOf(orderInfo.getRoomId()));
		req.setOpenId(openid);
		UnifiedOrderResponse resp = pay.unifiedOrder(req);

		System.out.println("createUnifiedOrder-----openid=" + openid + ",orderid=" + orderBKF.getBfOrderId());
		logger.debug("createUnifiedOrder-----openid=" + openid + ",bkfId=" + orderBKF.getBfOrderId()+ ",bkfSn=" + orderBKF.getBfOrderSn());

		// 失败抛出异常
		if (resp.getResultCode().equals("FAIL")) {
			throw new RuntimeException("FAIL:" + resp.getReturnMessage());
		}
		// 更新prepayid
		orderBKF.setPrepayId(resp.getPrepayId());
		updateNotNull(orderBKF);

		SortedMap<String, Object> generals = new TreeMap<>();
		generals.put("appId", wxCfg.getAppId());
		generals.put("nonceStr", Atools.getOneKeyS());
		generals.put("package", "prepay_id=" + resp.getPrepayId());
		generals.put("signType", "MD5");
		generals.put("timeStamp", String.valueOf(System.currentTimeMillis() / 1000));

		String sign = SignatureUtil.sign(generals, wxCfg.getAppkey());

		signModel.setAppId((String) generals.get("appId"));
		signModel.setTimeStamp((String) generals.get("timeStamp"));
		signModel.setNonceStr((String) generals.get("nonceStr"));
		signModel.setPackage((String) generals.get("package"));
		signModel.setSignType("MD5");
		signModel.setPaySign(sign);
		return signModel;
	}
	@Override
	@Transactional
	public void updateOrderBKF(OrderBreakfast orderBKF) {
		System.out.println("=======================早餐订单状态==========================="+orderBKF.getPayStatus()+"===================");
		this.updateNotNull(orderBKF);
		breakfastCouponService.addBrakefastCoupons(orderBKF);
	}

	@Override
	@Transactional
	public String addOrderBreakfastPC(OrderBreakfast obf) {
		try {
			String hotelId=obf.getHotelId();
			String mobile=obf.getMobile();
			MemberInfo member = this.memberInfoMapper.findMemberByMobile(hotelId, mobile);
			if(member==null) {
				MemberInfo memberNew=new MemberInfo();
				memberNew.setMobile(mobile);
				memberNew.setHotelId(hotelId);
				memberNew.setRealMoney(BigDecimal.ZERO);
				memberNew.setVirtMoney(BigDecimal.ZERO);
				memberNew.setLastLoginTime(new Date());
				memberNew.setGrade(HotelConstant.USER_GRADE_NEW);
				memberNew.setAddTime(new Date());
				this.memberInfoService.saveMember(memberNew);
				member = this.memberInfoMapper.findMemberByMobile(hotelId, mobile);
			}
			DiningRoom dnr=new DiningRoom();
			dnr.setHotelId(Long.valueOf(hotelId));
			DiningRoom dnm=this.diningRoomService.findDiningRoom(dnr);
			if(dnm==null) {
				return "404";
			}
			String unitPrice = dnm.getUnitPrice();
			BigDecimal unitPriceNum=new BigDecimal(unitPrice);
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
			Calendar calst = Calendar.getInstance();
			Calendar caled = Calendar.getInstance();
			Date start = sdf.parse(obf.getValidStart());//开始时间
			Date end=sdf.parse(obf.getValidEnd());//结束时间
		    calst.setTime(start);
		    caled.setTime(end);
		    //设置开始时间为0时   
		    calst.set(Calendar.HOUR_OF_DAY, 0);   
		    calst.set(Calendar.MINUTE, 0);   
			calst.set(Calendar.SECOND, 0); 
			//设置结束时间为0时   
			caled.set(Calendar.HOUR_OF_DAY, 0);   
			caled.set(Calendar.MINUTE, 0);   
			caled.set(Calendar.SECOND, 0); 
			//设置时间为11时
			/*Calendar calTiming = Calendar.getInstance();
			calTiming.set(Calendar.HOUR_OF_DAY, 11);   
			calTiming.set(Calendar.MINUTE, 0);   
			calTiming.set(Calendar.SECOND, 0);
			int days =1;
			if(start.getTime()>calTiming.getTime().getTime()) {
				days = ((int)(caled.getTime().getTime()/1000)-(int)(calst.getTime().getTime()/1000))/3600/24;
			}else {
				days = ((int)(caled.getTime().getTime()/1000)-(int)(calst.getTime().getTime()/1000))/3600/24 + 1;
			}*/
			int days = ((int)(caled.getTime().getTime()/1000)-(int)(calst.getTime().getTime()/1000))/3600/24 + 1;
		    BigDecimal sumPrice = unitPriceNum.multiply(new BigDecimal(obf.getNumDaily())).multiply(BigDecimal.valueOf(days));
		    obf.setMobile(member.getMobile());
		    obf.setUnitPrice(unitPriceNum);
		    obf.setSumPrice(sumPrice);
		    obf.setMemberId(member.getMemberId());
		    obf.setAddTime(new Date());
		    obf.setType("1");//'1赠送2购买'
			obf.setPayStatus("5");//5 不需支付订单
			//生成订单数据
			orderBreakfastMapper.addOrderBreakfast(obf);
			breakfastCouponService.addBrakefastCouponsPC(obf);
			return "0";
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return "500";
		}
	}

	@Override
	public List<OrderBreakfast> getOrderBKFCoupons(OrderBreakfast obf) {
		// TODO Auto-generated method stub
		return this.orderBreakfastMapper.getOrderBKFCoupons(obf);
	}
	/**
	 * 房间绑定早餐券
	 */
	@Override
	public void addOrderBreakfastByRoomInfo(OrderInfo orderInfo) {
		try {
			String hotelId=orderInfo.getHotelId()+"";
			String mobile=orderInfo.getMobile();
			MemberInfo member = this.memberInfoMapper.findMemberByMobile(hotelId, mobile);
			if(member==null) {
				MemberInfo memberNew=new MemberInfo();
				memberNew.setMobile(mobile);
				memberNew.setHotelId(hotelId);
				memberNew.setRealMoney(BigDecimal.ZERO);
				memberNew.setVirtMoney(BigDecimal.ZERO);
				memberNew.setLastLoginTime(new Date());
				memberNew.setGrade(HotelConstant.USER_GRADE_NEW);
				memberNew.setAddTime(new Date());
				this.memberInfoService.saveMember(memberNew);
				member = this.memberInfoMapper.findMemberByMobile(hotelId, mobile);
			}
			DiningRoom dnr=new DiningRoom();
			dnr.setHotelId(Long.valueOf(hotelId));
			DiningRoom dnm=this.diningRoomService.findDiningRoom(dnr);
			String unitPrice = dnm.getUnitPrice();
			BigDecimal unitPriceNum=new BigDecimal(unitPrice);
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
			Calendar calst = Calendar.getInstance();
			Calendar caled = Calendar.getInstance();
			Date start = sdf.parse(orderInfo.getCheckinTime());//开始时间
			Date end=sdf.parse(orderInfo.getCheckoutTime());//结束时间
		    calst.setTime(start);
		    calst.add(Calendar.DATE, 1); 
		    caled.setTime(end);
		    //设置开始时间为0时   
		    calst.set(Calendar.HOUR_OF_DAY, 0);   
		    calst.set(Calendar.MINUTE, 0);   
			calst.set(Calendar.SECOND, 0); 
			//设置结束时间为0时   
			caled.set(Calendar.HOUR_OF_DAY, 0);   
			caled.set(Calendar.MINUTE, 0);   
			caled.set(Calendar.SECOND, 0); 
			//设置时间为11时
			/*Calendar calTiming = Calendar.getInstance();
			calTiming.set(Calendar.HOUR_OF_DAY, 11);   
			calTiming.set(Calendar.MINUTE, 0);   
			calTiming.set(Calendar.SECOND, 0);
			int days =1;
			if(start.getTime()>calTiming.getTime().getTime()) {
				days = ((int)(caled.getTime().getTime()/1000)-(int)(calst.getTime().getTime()/1000))/3600/24;
			}else {
				days = ((int)(caled.getTime().getTime()/1000)-(int)(calst.getTime().getTime()/1000))/3600/24 + 1;
			}*/
			int days = ((int)(caled.getTime().getTime()/1000)-(int)(calst.getTime().getTime()/1000))/3600/24 + 1;
			//早餐政策 1、不含早餐 2、免费单早餐3、免费双早餐
			//根据房间id获取含早政策
			OrderBreakfast obf=new OrderBreakfast();
			RoomInfo roomInfo = this.roomInfoService.selectByKey(orderInfo.getRoomId());
			int roomCount=1;
			if(orderInfo.getRoomCount()!=null) roomCount=orderInfo.getRoomCount();
			if("1".equals(roomInfo.getPolBreakfast())) {
				return;
			}else if("2".equals(roomInfo.getPolBreakfast())) {
				obf.setNumDaily(1*roomCount);
			}else if("3".equals(roomInfo.getPolBreakfast())) {
				obf.setNumDaily(2*roomCount);
			}
			obf.setBkfOrderId(orderInfo.getOrderId());
			BigDecimal sumPrice = unitPriceNum.multiply(new BigDecimal(obf.getNumDaily())).multiply(BigDecimal.valueOf(days));
			obf.setValidStart(sdf.format(calst.getTime()));
			obf.setValidEnd(sdf.format(end));
			obf.setMobile(member.getMobile());
		    obf.setUnitPrice(unitPriceNum);
		    obf.setSumPrice(sumPrice);
		    obf.setMemberId(member.getMemberId());
		    obf.setAddTime(new Date());
		    obf.setType("1");//'1赠送2购买'
			obf.setPayStatus("4");//4 来源于订单发放
			obf.setRoomNo(roomInfo.getRoomId()+"");
			obf.setHotelId(hotelId);
			obf.setAmount(days*obf.getNumDaily());
			//生成订单数据
			orderBreakfastMapper.addOrderBreakfast(obf);
			breakfastCouponService.addBrakefastCouponsPC(obf);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	@Override
	public void delCouponsByCon(OrderBreakfast obf) {
		this.orderBreakfastMapper.delCouponsByCon(obf);
	}
}
